import * as THREE from "three";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
import { DragControls } from "three/examples/jsm/controls/DragControls.js";
import { FirstPersonControls } from "three/examples/jsm/controls/FirstPersonControls.js";
// import {FlyControls} from 'three/examples/jsm/controls/FlyControls.js';
// import CameraControls from 'camera-controls';

import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
import * as TWEEN from "three/examples/jsm/libs/tween.module.js";

import Stats from "three/examples/jsm/libs/stats.module.js";

export class VRHouse {
  constructor(options) {
    this.options = Object.assign(
      {
        container: document.body,
      },
      options
    );
    //开启/关闭光源辅助器
    this.enableLightHelper = true;
    //开启/关闭光影相机辅助器
    this.enableLightCameraHelper = false;

    // 时间
    this.clock = new THREE.Clock();
    // gltf加载器
    this.gltfLoader = new GLTFLoader();
    //纹理贴图加载器
    this.textureLoader = new THREE.TextureLoader();

    //可选择的物体集合
    this.selectEnabledMeshs = [];
    //可点击的物体集合
    this.clickEnabledMeshs = [];
    //需要更新的物体列表，每个对象必须有update函数
    this.updateObjects = [];
  }
  //初始化场景
  initScene() {
    // 场景
    this.scene = new THREE.Scene();
  }

  //初始化相机
  initCamera() {
    // 相机
    const { clientWidth, clientHeight } = this.options.container; // 获取容器宽高
    this.cameraPersp = new THREE.PerspectiveCamera(
      45,
      clientWidth / clientHeight,
      0.1,
      1000
    ); // 创建透视相机
    this.cameraOrtho = new THREE.OrthographicCamera(
      clientWidth / -16,
      clientWidth / 16,
      clientHeight / 16,
      clientHeight / -16,
      0.1,
      1000
    ); // 创建正交相机
    this.camera = this.cameraPersp; //默认使用透视相机
    this.camera.position.set(0, 2, 10); // 设置相机位置
    this.camera.lookAt(0, 0, 0); // 相机看向坐标原点
    this.scene.add(this.camera);
  }

  //初始化渲染器
  initRenderer() {
    // 渲染器
    this.renderer = new THREE.WebGLRenderer({
      antialias: true, // 抗锯齿
    });
    this.renderer.setPixelRatio(window.devicePixelRatio); // 设置设备像素比
    const { clientWidth, clientHeight } = this.options.container; // 获取容器宽高
    this.renderer.setSize(clientWidth, clientHeight); // 设置渲染器大小
    //this.renderer.setClearColor(0x000000, 1);// 设置背景色

    // 阴影
    this.renderer.shadowMap.enabled = true; // 开启阴影
    // this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 设置阴影类型

    this.options.container.appendChild(this.renderer.domElement); // 将渲染器添加到容器中
    //渲染器渲染,在动画循环中调用
    // this.renderer.render(this.scene, this.camera);
  }

  //初始化键盘监听
  initKeyboardEventListener() {
    const that = this;
    const control = that.transformControls;
    const orbit = that.orbitControls;
    const cameraPersp = that.cameraPersp;
    const cameraOrtho = that.cameraOrtho;
    that.camera = cameraPersp;
    //处理键盘事件
    window.addEventListener("keydown", function (event) {
      console.log(control.object);

      

      if (!control.object) return;
      switch (event.keyCode) {
        case 81: // Q
          control.setSpace(control.space === "local" ? "world" : "local");
          break;

        case 16: // Shift
          control.setTranslationSnap(100);
          control.setRotationSnap(THREE.MathUtils.degToRad(15));
          control.setScaleSnap(0.25);
          break;

        case 84: // T
          control.setMode("translate");
          break;

        case 82: // R
          control.setMode("rotate");
          break;

        case 83: // S
          control.setMode("scale");
          break;

        case 67: // C
          const position = that.camera.position.clone();

          that.camera = that.camera.isPerspectiveCamera
            ? cameraOrtho
            : cameraPersp;
          that.camera.position.copy(position);

          orbit.object = that.camera;
          control.camera = that.camera;

          that.camera.lookAt(orbit.target.x, orbit.target.y, orbit.target.z);
          that.onWindowResize();
          break;

        case 86: // V
          const randomFoV = Math.random() + 0.1;
          const randomZoom = Math.random() + 0.1;

          cameraPersp.fov = randomFoV * 160;
          cameraOrtho.bottom = -randomFoV * 500;
          cameraOrtho.top = randomFoV * 500;

          cameraPersp.zoom = randomZoom * 5;
          cameraOrtho.zoom = randomZoom * 5;
          that.onWindowResize();
          break;

        case 187:
        case 107: // +, =, num+
          control.setSize(control.size + 0.1);
          break;

        case 189:
        case 109: // -, , num-
          control.setSize(Math.max(control.size - 0.1, 0.1));
          break;

        case 88: // X
          control.showX = !control.showX;
          break;

        case 89: // Y
          control.showY = !control.showY;
          break;

        case 90: // Z
          control.showZ = !control.showZ;
          break;

        case 32: // Spacebar
          control.enabled = !control.enabled;
          if (!control.enabled) {
            control.showX = false;
            control.showY = false;
            control.showZ = false;
            //control.attach(control.object );
          } else {
            control.showX = true;
            control.showY = true;
            control.showZ = true;
          }
          break;

        case 27: // Esc
          control.reset();
          break;
      }
    });

    window.addEventListener("keyup", function (event) {
      switch (event.keyCode) {
        case 16: // Shift
          control.setTranslationSnap(null);
          control.setRotationSnap(null);
          control.setScaleSnap(null);
          break;
      }
    });
  }

  initDomEventListener() {
    // 处理窗口大小改变事件
    window.addEventListener("resize", this.onWindowResize.bind(this));

    //全屏显示
    const fullscreenButton = document.getElementById("btnFullscreen");
    fullscreenButton.addEventListener(
      "click",
      this.toggleFullscreen.bind(this),
      false
    );
  }

  initStats() {
    this.stats = new Stats();
    this.stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
    document.body.appendChild(this.stats.dom);
  }

  loadStandarCube(material = null) {
    this.mesh = new THREE.Mesh(
      new THREE.BoxGeometry(1, 1, 1),
      material || new THREE.MeshBasicMaterial({ color: 0x00ff00 })
    );
    const mesh = this.mesh;
    // mesh.position.x = -1; // 设置物体位置
    mesh.name = "Cube"; // 设置物体的名字

    mesh.castShadow = true; // 开启物体阴影
    mesh.receiveShadow = true; // 开启物体接收阴影

    this.clickEnabledMeshs.push(mesh); // 将物体添加到可点击物体数组中
    this.selectEnabledMeshs.push(mesh); // 将物体添加到事件物体数组中
    this.scene.add(mesh); // 添加到场景中
  }
  //初始化射线投射器
  initRaycaster() {
    this.raycaster = new THREE.Raycaster();
    this.raycasterHandlers = [];

    //获取父级是场景的物体
    function getParent(obj3d){

         if(obj3d.parent.isScene){
             return obj3d;
         }else if(obj3d.parent){
             return getParent(obj3d.parent);
         }else{
             return null;
         }
    }

    //点击事件变成可点击物体变换控制器
    this.addRaycasterListener(
      "select",
      this.selectEnabledMeshs,
      (intersect) => {
        
        console.log("select", intersect);
        const control = this.transformControls;
        const parent = getParent(intersect.object);
        // const parent = intersect.object;
        control.attach(parent); // 绑定变换控制器
        control.enabled = true; // 启用变换控制器
        control.showX = true;
        control.showY = true;
        control.showZ = true;
      }
    );

    // this.addRaycasterListener("click", this.clickEnabledMeshs, (intersect) => {
    //   console.log("click", intersect);
    //   const direct = intersect.point.clone().sub(this.camera.position).normalize();
    //   this.camera.position.copy(intersect.point);
    //   this.camera.lookAt(direct);
    // });

    // this.removeRaycasterListener("select",handleIntersect);

    // function handleIntersect(intersect) {
    //   console.log("handleIntersect",intersect);
    // }
    // this.addRaycasterListener("select",this.selectEnabledMeshs,handleIntersect);

    // this.addRaycasterListener("select",this.selectEnabledMeshs,(intersect)=>{
    //   console.log("select",intersect);
    // });
  }
  //移除canvas内部元素点击事件处理
  removeRaycasterListener(eventName, callback) {
    // debugger
    if (this.raycasterHandlers.length > 0) {
      if (callback) {
        const index = this.raycasterHandlers.findIndex(
          (item) => item.eventName === eventName && item.callback === callback
        );
        if (index >= 0) {
          const handler = this.raycasterHandlers[index].handler;
          this.options.container.removeEventListener("click", handler);
          this.raycasterHandlers.splice(index, 1);
        }
      } else {
        for (let i = this.raycasterHandlers.length - 1; i >= 0; i--) {
          if (this.raycasterHandlers[i].eventName === eventName) {
            const handler = this.raycasterHandlers[i].handler;
            this.options.container.removeEventListener("click", handler);
            this.raycasterHandlers.splice(i, 1);
          }
        }
      }
    }
  }
  //添加canvas内部元素点击事件处理
  addRaycasterListener(eventName, enableMeshs = [], callback) {
    const pointer = new THREE.Vector2();
    const handler = (event) => {
      const { clientWidth, clientHeight } = this.options.container; // 获取容器宽高
      pointer.x = (event.clientX / clientWidth) * 2 - 1;
      pointer.y = -(event.clientY / clientHeight) * 2 + 1;

      this.raycaster.setFromCamera(pointer, this.camera); // 设置射线
      const intersects = this.raycaster.intersectObjects(enableMeshs,true); // 计算射线经过的所有可点击物体
      // console.log(enableMeshs);
      const intersect = intersects[0];
      if (intersect) {
        callback(intersect);
      }
    };
    this.options.container.addEventListener("click", handler);
    this.raycasterHandlers.push({ eventName, handler, callback: callback });
  }
  //初始化环境光源
  initAmbientLight() {
    const ambientLight = new THREE.AmbientLight(0xffffff, 7);
    this.scene.add(ambientLight);
  }
  //初始化平行光源
  initDirectionalLight() {
    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
    directionalLight.position.set(0, 3, 0);
    directionalLight.target.position.set(-10, 0, 0);

    directionalLight.castShadow = true;
    // directionalLight.shadow.mapSize.width = 1024;
    // directionalLight.shadow.mapSize.height = 1024;

    // directionalLight.shadow.camera.near = 0.2;
    // directionalLight.shadow.camera.far = 500;
    // directionalLight.shadow.camera.left = -50;
    // directionalLight.shadow.camera.right = 50;
    // directionalLight.shadow.camera.top = 50;
    // directionalLight.shadow.camera.bottom = -50;

    this.scene.add(directionalLight);

    if (this.enableLightHelper) {
      //方向光帮助器
      const directionalLightHelper = new THREE.DirectionalLightHelper(
        directionalLight,
        1
      );
      this.scene.add(directionalLightHelper);
    }
    if (this.enableLightCameraHelper) {
      //方向光相机帮助器
      const cameraHelper = new THREE.CameraHelper(
        directionalLight.shadow.camera
      );
      this.scene.add(cameraHelper);
    }
  }
  //初始化点光源
  initPointLight() {
    const pointLight = new THREE.PointLight(0xffffff, 9);

    pointLight.position.set(1, 3, 1);
    this.scene.add(pointLight);

    //点光源阴影
    pointLight.castShadow = true;
    // pointLight.shadow.mapSize.width = 1024;
    // pointLight.shadow.mapSize.height = 1024;

    //pointLight产生PerspectiveCamera 透视相机
    pointLight.shadow.camera.near = 0.5;
    pointLight.shadow.camera.far = 500;
    // pointLight.shadow.camera.aspect = 1;
    // pointLight.shadow.camera.fov = 70;

    //点光源帮助器
    if (this.enableLightHelper) {
      const pointLightHelper = new THREE.PointLightHelper(pointLight, 1);
      this.scene.add(pointLightHelper);
    }

    //点光源相机帮助器
    if (this.enableLightCameraHelper) {
      const cameraHelper = new THREE.CameraHelper(pointLight.shadow.camera);
      this.scene.add(cameraHelper);
      //selectEnabledMeshs.push(cameraHelper);//可选中物体列表中添加可选中物体
    }
  }

  //初始化聚光灯
  initSpotLight() {
    const spotLight = new THREE.SpotLight(0xffffff, 2);
    spotLight.angle = Math.PI / 4; //光照角度 弧度制
    spotLight.penumbra = 0.1; //光照扩散范围 0 无扩散 1 扩散至原点
    spotLight.decay = 2; //衰减系数 值越大衰减越快
    spotLight.distance = 0; //光照距离 0 无限远

    spotLight.position.set(0, 3, 0); //光源位置
    spotLight.target.position.set(0, 0, 0); //光源目标点

    spotLight.castShadow = true; //是否投射阴影
    // spotLight.shadow.map.type = THREE.PCFSoftShadowMap; //阴影贴图类型
    spotLight.shadow.mapSize.width = 1024; //阴影贴图大小
    spotLight.shadow.mapSize.height = 1024; //阴影贴图大小

    //透视相机
    // spotLight.shadow.camera.near = 0.1; //阴影相机近端面
    // spotLight.shadow.camera.far = 100; //阴影相机远端面
    // spotLight.shadow.camera.fov = 90; //阴影相机视角度
    // spotLight.shadow.camera.aspect = 1; //阴影相机纵横比

    //spotLight.shadow.bias = -0.001; //阴影偏移量 值越大偏移越大

    this.scene.add(spotLight);

    // //聚光灯帮助器
    if (this.enableLightHelper) {
      const spotLightHelper = new THREE.SpotLightHelper(spotLight);
      this.scene.add(spotLightHelper);
    }

    //聚光灯相机帮助器
    if (this.enableLightCameraHelper) {
      const cameraHelper = new THREE.CameraHelper(spotLight.shadow.camera);
      this.scene.add(cameraHelper);
    }
  }

  //初始化坐标轴
  initAxesHelper() {
    const axesHelper = new THREE.AxesHelper(3);
    this.scene.add(axesHelper);
  }
  //初始化网格帮助器
  initGridHelper() {
    const gridHelper = new THREE.GridHelper(20, 20, "red", 0xffffff);
    gridHelper.material.opacity = 0.2;
    gridHelper.material.transparent = true;
    this.scene.add(gridHelper);
  }
  //初始化轨道控制器
  initOrbitControls() {
    this.orbitControls = new OrbitControls(
      this.camera,
      this.renderer.domElement
    );
    //this.orbitControls.target.set(0, 2, 0);
  }

  //   initCameraControls() {
  //     this.cameraControls = new CameraControls(this.camera, this.renderer.domElement);
  //     //this.cameraControls.update();
  //   }

  // initFlyControls() {
  //   this.flyControls = new FlyControls(this.camera, this.renderer.domElement);
  //   // this.flyControls.movementSpeed = 10;
  //   // this.flyControls.domElement = this.renderer.domElement;
  //   // this.flyControls.rollSpeed = Math.PI / 24;
  //   // this.flyControls.autoForward = false;
  //   this.flyControls.dragToLook = true;//开启鼠标拾取
  //   this.flyControls.update();
  // }

  initFirstPersonControls() {
    this.firstPersonControls = new FirstPersonControls(
      this.camera,
      this.renderer.domElement
    );
    this.firstPersonControls.activeLook = false; //关闭鼠标拾取
    // this.firstPersonControls.movementSpeed = 10;
    // this.firstPersonControls.lookSpeed = 0.1;
  }

  //初始化变换控制器
  initTransformControls() {
    this.transformControls = new TransformControls(
      this.camera,
      this.renderer.domElement
    );
    // this.transformControls.addEventListener( 'objectChange', function () {
    //   const object = this.transformControls.object
    // });
    this.transformControls.setSpace("local");
    this.transformControls.setMode("translate");

    const that = this;
    this.transformControls.addEventListener(
      "dragging-changed",
      function (event) {
        that.orbitControls.enabled = !event.value; //启用/禁用轨道控制器
      }
    );

    //对象变换事件
    this.transformControls.addEventListener("objectChange", () => {
      const { position, rotation, scale } = this.transformControls.object;
      console.log(
        JSON.stringify({
          position,
          rotation: { x: rotation.x, y: rotation.y, z: rotation.z },
          scale,
        })
      ); //获取变换后的位置
    });
    this.scene.add(this.transformControls);
  }

  //窗口变化处理函数
  onWindowResize() {
    //console.log(this.options)
    const { clientWidth, clientHeight } = this.options.container; // 获取容器宽高
    const aspect = clientWidth / clientHeight;
    // this.camera.aspect = clientWidth / clientHeight;
    // this.camera.updateProjectionMatrix();
    this.cameraPersp.aspect = aspect; //camera中的参数修改后必须更新投影矩阵
    this.cameraPersp.updateProjectionMatrix();

    this.cameraOrtho.left = this.cameraOrtho.bottom * aspect;
    this.cameraOrtho.right = this.cameraOrtho.top * aspect;
    this.cameraOrtho.updateProjectionMatrix(); //camera中的参数修改后必须更新投影矩阵

    this.renderer.setSize(clientWidth, clientHeight); // 设置渲染器宽高

    // this.camera.aspect = clientWidth / clientHeight;
    // this.camera.updateProjectionMatrix();
    // this.renderer.setSize( clientWidth, clientHeight );// 设置渲染器宽高
  }

  //循环渲染函数
  animate() {
    const delta = this.clock.getDelta();
    requestAnimationFrame(() => {
      this.animate();
    });

    if (this.stats) {
      this.stats.update(); //更新性能插件
    }

    if (this.orbitControls) {
      this.orbitControls.update(delta); //更新轨道控制器
    }
    // if(this.cameraControls){
    //   this.cameraControls.update(delta);//更新相机控制器
    //}
    if (this.flyControls) {
      this.flyControls.update(delta); //更新飞行控制器
    }
    if (this.firstPersonControls) {
      this.firstPersonControls.update(delta); //更新第一人称控制器
    }

    TWEEN.update(); //更新补间动画

    this.renderer.render(this.scene, this.camera); //渲染器渲染
  }

  // 加载展厅
  async loadHall(params) {
    const { url, position, scale, onProgress } = params;
    const gltf = await this.loadGltf({ url, onProgress });
    const hall = gltf.scene;
    if (position) {
      hall.position.set(position.x, position.y, position.z);
    }
    if (scale) {
      hall.scale.set(scale.x, scale.y, scale.z);
    }
    this.selectEnabledMeshs.push(hall);
    this.scene.add(hall);
    return gltf;
  }
  // 加载场景物体
  loadGltf(params) {
    const { url, onProgress } = params;
    return new Promise((resolve, reject) => {
      this.gltfLoader.load(
        url,
        (gltf) => {
          resolve(gltf);
        },
        (progress) => {
          if (onProgress) {
            onProgress(progress);
          }
        },
        (err) => {
          reject(err);
        }
      );
    });
  }

  // 加载纹理贴图
  loadTexture(params) {
    const { url } = params;
    return new Promise((resolve, reject) => {
      this.textureLoader.load(
        url,
        (texture) => {
          resolve(texture);
        },
        undefined,
        (err) => {
          reject(err);
        }
      );
    });
  }

  //加载地板
  loadFloor() {
    const geometry = new THREE.PlaneGeometry(50, 50);
    const material = new THREE.MeshStandardMaterial({
      color: 0x808080,
      side: THREE.DoubleSide,
      metalness: 0, //金属度 0 非金属 1 金属
      roughness: 0.1, //粗糙度 0 无粗糙 1 粗糙
    });
    const floor = new THREE.Mesh(geometry, material);
    this.floor = floor;
    floor.name = "floor";
    floor.rotation.x = -Math.PI / 2;

    floor.receiveShadow = true;

    this.scene.add(floor); //场景中添加地板
    this.clickEnabledMeshs.push(floor); //可点击物体列表中添加可点击物体
    this.selectEnabledMeshs.push(floor); //可选中物体列表中添加可选中物体
  }

  //加载房子模型
  loadHourseModel() {
    const loader = this.gltfLoader;
    loader.load(
      "models/房间.glb",
      (gltf) => {
        const hourse = gltf.scene;
        console.log(hourse);
        hourse.position.set(0, 1, 0);
        // hourse.scale.set(0.01, 0.01, 0.01);
        this.scene.add(hourse);
        this.clickEnabledMeshs.push(hourse); //可点击物体列表中添加可点击物体
        this.selectEnabledMeshs.push(hourse); //可选中物体列表中添加可选中物体
      },
      (xhr) => {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },
      (err) => {
        console.error(err);
      }
    );
  }

  //初始带有纹理贴图的立方物体
  initMeshWithTexture() {
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshStandardMaterial({
      color: "red",
      map: textureLoader.load("textures/hall.png"),
    });
    meshWithTexture = new THREE.Mesh(geometry, material);
    meshWithTexture.position.x = 1;
    scene.add(meshWithTexture); //场景中添加立方体

    selectEnabledMeshs.push(meshWithTexture); //可选中物体列表中添加可选中物体
  }

  //初始化GUI
  initGui() {
    const gui = new GUI();
    this.gui = gui;

    const mesh = this.floor; //指定mesh为地板

    const folder1 = gui.addFolder("自定义控制台输出");
    let options = {
      color: "red",
      isOpen: true,
    };
    folder1.add(options, "isOpen").onFinishChange(function (value) {
      console.log(value);
    }).name("是否开启");
    folder1
        .add(options, "color", ["red", "green", "blue"])
        .onFinishChange(function (value) {
          console.log(value);
          switch (value) {
            case "red":
              // mesh.material.color.set(0xff0000);
              // console.log("red");
              break;
            case "green":
              // mesh.material.color.set(0x00ff00);
              // console.log("green");
              break;
            case "blue":
              // mesh.material.color.set(0x0000ff);
              // console.log("blue");
              break;
          }
        });
    
    if (mesh) {      
      const leftMove = () => {
        // this.setAnimation({ x: 0 }, { x: Math.PI / 4 }, mesh);
        mesh.position.x += -1;
      };
      const rightMove = () => {
        mesh.position.x += 1;
      };
      let floorOptions = {       
        floorColor: 0x00ff00,
        leftMove,
        rightMove,
      };
      const folder = gui.addFolder("地板");
      //添加子项
      folder.add(mesh.position, "x", -5, 5).step(0.1).name("X轴位置");
      folder.add(mesh.position, "y", -5, 5).step(0.1).name("Y轴位置");
      folder.add(mesh.position, "z", -5, 5).step(0.1).name("Z轴位置");

      folder
        .addColor(floorOptions, "floorColor")
        .name("颜色")
        .onChange(function (value) {
          mesh.material.color.set(value);
        });
      folder.add(floorOptions, "leftMove").name("左移");
      folder.add(floorOptions, "rightMove").name("右移");
    }
  }

  //设置补间动画
  setAnimation(start, end, mesh, callback) {
    //const start={x:0,y:0,z:0};
    //const end={x:1,y:1,z:1};
    const tween = new TWEEN.Tween(start)
      .to(end, 1000)
      .easing(TWEEN.Easing.Quadratic.Out);
    tween.onUpdate(function (that) {
      mesh.rotation.x = that.x;
      if (callback) {
        callback(that);
      }
    });
    tween.start();
  }

  //全屏显示
  toggleFullscreen() {
    const isFullscreen =
      document.fullscreenElement ||
      document.webkitFullscreenElement ||
      document.mozFullScreenElement ||
      document.msFullscreenElement;
    if (isFullscreen) {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      }
    } else {
      const container = document.body;
      if (container.requestFullscreen) {
        container.requestFullscreen();
      } else if (container.webkitRequestFullscreen) {
        container.webkitRequestFullscreen();
      } else if (container.mozRequestFullScreen) {
        container.mozRequestFullScreen();
      } else if (container.msRequestFullscreen) {
        container.msRequestFullscreen();
      }
    }
  }

  init() {
    // 初始化场景
    this.initScene();

    // 初始化相机
    this.initCamera();

    // 初始化渲染器
    this.initRenderer();

    //坐标轴
    this.initAxesHelper();

    //网格帮助器
    this.initGridHelper();

    // 加载初始光源
    this.initAmbientLight();
    this.initDirectionalLight();

    // this.initPointLight();
    // this.initSpotLight();

    // 加载初始场景物体
    this.loadFloor();
    // this.loadStandarCube();

    //轨道控制器
    this.initOrbitControls();
    //变换控制器
    this.initTransformControls();
    //相机控制器
    //this.initCameraControls();
    //飞行控制器(无法用)
    //this.initFlyControls();
    //第一人称控制器
    //this.initFirstPersonControls();

    //初始化射线投射器(射线从摄像机发出，检测场景中可点击物体，并触发相应事件(canvas画面内部鼠标点击事件))
    this.initRaycaster();
    // Dom事件监听初始化
    this.initDomEventListener();
    // //键盘事件监听初始化
    this.initKeyboardEventListener();

    //属性面板初始化
    this.initGui();

    //性能插件
    this.initStats();

    //开启循环渲染
    this.animate();
  }

  //测试用
  test1() {
    const cube = new THREE.Mesh(
      new THREE.BoxGeometry(1, 1, 1),
      new THREE.MeshBasicMaterial({
        color: 0x00ff00,
      })
    );

    const cube2 = new THREE.Mesh(
      new THREE.BoxGeometry(1, 1, 1),
      new THREE.MeshBasicMaterial({
        color: 0x00ffff,
      })
    );

    cube2.position.x = 2;

    const controls = new DragControls(
      [cube, cube2],
      this.camera,
      this.renderer.domElement
    );
    this.scene.add(cube, cube2);
  }
}

export default VRHouse
